package com.reebake.ideal.storage.controller.client;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.reebake.ideal.storage.client.FileDownloadClient;
import com.reebake.ideal.storage.service.FileDetailService;
import com.reebake.ideal.storage.util.StorageUtil;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.SneakyThrows;
import org.dromara.x.file.storage.core.FileInfo;
import org.dromara.x.file.storage.core.FileStorageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.io.OutputStream;

@RestController
@RequestMapping("/client/storage/file")
public class FileDownloadClientController implements FileDownloadClient {
    @Autowired
    private FileStorageService fileStorageService;
    @Autowired
    private FileDetailService fileDetailService;

    /**
     * 下载,支持大文件
     * @param fileDetailId
     * @param url
     * @param dispositionType attachment or inline
     * @return
     */
    @SneakyThrows
    public ResponseEntity<Resource> download(@RequestParam(required = false) String fileDetailId
            , @RequestParam(required = false) String url
            , @RequestParam(required = false) String dispositionType) {
        Assert.isTrue(StrUtil.isNotBlank(fileDetailId) || StrUtil.isNotBlank(url), "url or fileDetailId is null");
        if(StrUtil.isBlank(dispositionType)) {
            dispositionType = "attachment";
        }
        // 获取文件信息
        FileInfo fileInfo = null;
        if(StrUtil.isNotBlank(fileDetailId)){
            fileInfo = StorageUtil.toFileInfo(fileDetailService.getById(fileDetailId));
        }
        if(StrUtil.isNotBlank(url)) {
            fileInfo = fileStorageService.getFileInfoByUrl(url);
        }
        String filename = fileInfo.getFilename();
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = servletRequestAttributes.getRequest();
        if(ObjUtil.isNull(request)
                || !request.getRequestURI().startsWith("/client")){
            byte[] bytes = fileStorageService.download(fileInfo).bytes();
            return ResponseEntity.ok().body(new ByteArrayResource(bytes));
        }
        HttpServletResponse response = servletRequestAttributes.getResponse();
        fileStorageService.download(fileInfo).inputStream(in -> {
            byte[] buffer = new byte[1024];
            int len = 0;
            try {
                OutputStream os = response.getOutputStream();
                while ((len = in.read(buffer)) != -1) {
                    os.write(buffer, 0, len);
                }
            }catch (Exception e) {
                throw new RuntimeException(e);
            }
        });

        return ResponseEntity.ok()
                .header("Content-Disposition", dispositionType + "; filename=\"" + filename + "\"")
                .header("Content-Type","application/octet-stream")
                .header("Content-Length", "" + fileInfo.getSize())
                .build();
    }
}
